﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Web;
using System.Threading;
using System.IO;

namespace H2.NET.TaskRob
{
    public class OpenTasksInstance
    {
        public static OpenTasks OpenTasks;
        static OpenTasksInstance()
        {
            OpenTasks = new OpenTasks();
        }
    }

    public class OpenTasks
    {
        public Hashtable OpenTask = new Hashtable();

        #region ctor
        public OpenTasks()
        {
        }
        #endregion

        #region IsOverFlow
        public bool IsOverFlow(string Process, int Incident, string Step, string UserName)
        {
            bool flg = false;
            Monitor.Enter(OpenTask);
            try
            {
                string key = Process + "~" + Incident.ToString() + "~" + Step;
                if (OpenTask.Contains(key))
                {
                    Tasks tsk = (Tasks)OpenTask[key];
                    flg = tsk.MinResp <= tsk.User.Count;

                    foreach (TasksUser tskUser in tsk.User)
                    {
                        if (tskUser.UserName.Equals(UserName))
                        {
                            flg = false;
                            break;
                        }
                    }
                }
                else
                {
                    flg = false;
                }
            }
            finally
            { 
                Monitor.Exit(OpenTask);
            }

            return flg;
        }
        #endregion

        #region GetRobUser
        public string GetRobUser(string Process, int Incident, string Step)
        {
            string user = "";
            Monitor.Enter(OpenTask);
            try
            {
                string key = Process + "~" + Incident.ToString() + "~" + Step;
                if (OpenTask.Contains(key))
                {
                    Tasks tsk = (Tasks)OpenTask[key];
                    foreach (TasksUser tskUser in tsk.User)
                    {
                        user += (string.IsNullOrEmpty(user) ? "" : ",") + tskUser.UserFullName;
                    }
                }
            }
            finally
            {
                Monitor.Exit(OpenTask);
            }

            return user;
        }
        #endregion

        #region SetTaskOpen
        public void SetTaskOpen(string Process, int Incident, string Step, int MinResp, string UserName, string UserFullName)
        {
            Process  = Process == null ? "" : Process;
            Step     = Step == null ? "" : Step;

            if (!string.IsNullOrEmpty(Process))
            {
                Monitor.Enter(OpenTask);
                try
                {
                    string key = Process + "~" + Incident + "~" + Step;
                    if (OpenTask[key] == null)
                    {
                        Tasks tsk = new Tasks();
                        tsk.Process  = Process;
                        tsk.Incident = Incident;
                        tsk.Step     = Step;
                        tsk.MinResp  = MinResp;

                        tsk.User.Add(new TasksUser(UserName, UserFullName));
                        OpenTask[key] = tsk;
                    }
                    else
                    {
                        Tasks tsk = (Tasks)OpenTask[key];

                        //检查是否过期
                        for (int i = 0; i < tsk.User.Count; i++)
                        {
                            if ((System.DateTime.Now.Ticks - tsk.User[i].TimerPeriod.Ticks) / 600000000 > 3 )
                            {
                                tsk.User.RemoveAt(i);
                                i--;
                            }
                        }

                        bool flg = true;
                        for (int i = 0; i < tsk.User.Count; i++)
                        {
                            if (tsk.User[i].UserName.Equals(UserName))
                            {
                                tsk.User[i].TimerPeriod = System.DateTime.Now;
                                flg = false;
                            }
                        }

                        if (flg && tsk.MinResp > tsk.User.Count)
                        {
                            tsk.User.Add(new TasksUser(UserName, UserFullName));
                        }
                    }
                }
                finally
                {
                    Monitor.Exit(OpenTask);
                }
            }
        }
        #endregion

        #region UpldateTaskStatus
        public void UpldateTaskStatus(bool flg, string Process, int Incident, string Step, string UserName, string UserFullName)
        {
            Process = Process == null ? "" : Process;
            Step = Step == null ? "" : Step;

            if (!string.IsNullOrEmpty(Process))
            {
                Monitor.Enter(OpenTask);
                try
                {
                    string key = Process + "~" + Incident + "~" + Step;
                    if (OpenTask[key] != null)
                    {
                        Tasks tsk = (Tasks)OpenTask[key];
                        if (flg)
                        {
                            bool flg2 = true;
                            for (int i = 0; i < tsk.User.Count; i++ )
                            {
                                if (tsk.User[i].UserName.Equals(UserName))
                                {
                                    tsk.User[i].TimerPeriod = System.DateTime.Now;
                                    flg2 = false;
                                    break;
                                }
                            }

                            if (flg2)
                            {
                                tsk.User.Add(new TasksUser(UserName, UserFullName));
                            }
                        }
                        else
                        {
                            for (int i = 0; i < tsk.User.Count; i++)
                            {
                                if (tsk.User[i].UserName.Equals(UserName))
                                {
                                    tsk.User.RemoveAt(i);
                                    break;
                                }
                            }

                            if (tsk.User.Count == 0)
                            {
                                OpenTask.Remove(key);
                            }
                        }
                    }
                }
                finally
                {
                    Monitor.Exit(OpenTask);
                }
            }
        }
        #endregion

        #region SetTaskClose
        public void SetTaskClose(string Process, int Incident, string Step)
        {
            Monitor.Enter(OpenTask);
            try
            {
                string key = Process + "~" + Incident + "~" + Step;
                if (OpenTask.Contains(key))
                {
                    OpenTask.Remove(key);
                }
            }
            finally
            {
                Monitor.Exit(OpenTask);
            }
        }
        #endregion

        #region Log
        public static void Log(string strInfo)
        {
            FileInfo fleLog = new FileInfo(@"c:\OpenTasks.log");
            StreamWriter steWrt = fleLog.AppendText();
            steWrt.WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "]: " + strInfo);
            steWrt.Close();
        }
        #endregion

        #region Tasks、TasksUser
        public class Tasks
        {
            public Tasks()
            {           
            }

            public List<TasksUser> User { get { return _User; } set { _User = value; } }
            private List<TasksUser> _User = new List<TasksUser>();

            public string Process { get { return _Process; } set { _Process = value; } }
            private string _Process;

            public int Incident { get { return _Incident; } set { _Incident = value; } }
            private int _Incident;

            public string Step { get { return _Step; } set { _Step = value; } }
            private string _Step;

            public int MinResp { get { return _MinResp; } set { _MinResp = value; } }
            private int _MinResp;
        }

        public class TasksUser
        {
            public TasksUser(string UserName, string UserFullName)
            {
                _UserName     = UserName;
                _UserFullName = UserFullName;
                _TimerPeriod  = System.DateTime.Now;
            }

            public string UserName { get { return _UserName; } set { _UserName = value; } }
            private string _UserName;

            public string UserFullName { get { return _UserFullName; } set { _UserFullName = value; } }
            private string _UserFullName;

            public DateTime TimerPeriod { get { return _TimerPeriod; } set { _TimerPeriod = value; } }
            private DateTime _TimerPeriod;
        }
        #endregion
    }
}
